﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;

namespace upres
{
    public partial class Form1 : Form
    {
        private static String[] account = null;                             //chứa danh sách các tài khoản
        private static CookieContainer _cookie = null;                      //chứa cookie
        private static string server ;                                      //server VD : http://ts3.travian.com
        private static String username ;                                    //username lúc đăng nhập
        private static String password ;                                    //pass lúc đăng nhập
        private static VillageInfo[] ListVillage;                           //thông tin tất cả các làng của account
        private static int cVil = -1;                                       //làng hiện tại đang được hiển thị trên GUI
        private String path = @"C:\Users\KID\Desktop\dorf1vn.txt"; //dùng để test khi không có mạng
        private static Image[] res_map = new Image[14];                     //các loại map ứng với 6c,7c,9c,12c . . . 
        List<object> todoList = new List<object>();                         //list thực hiện thao tác upgrade, hễ có task là send

        Boolean startStop = false;                                          //điều khiển chương trình khi nhấn Start / Stop
        System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();   //đếm ngược thời gian chờ xây nhà  , 1s kiểm tra 1 lần
        System.Timers.Timer timer2 = new System.Timers.Timer();             //thực hiện ugrade, 5s kiểm tra 1 lần
        Random random = new Random();                                       //dùng để tạo thời gian random
        public static TabPage[] ListTabpageVillage = new TabPage[15];                //chứa tên làng, click vào làng nào hiển thị làng đó, mới có 15 làng thôi
        delegate void deGUIshowvillage(VillageInfo vinfo);                  //delegate hiển thị ra GUI

        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// send post to upgrade res
        /// </summary>
        /// <param name="newdid">id of village</param>
        /// <param name="resid">position of res</param>
        /// <returns>if successfully, return true, if cannot up, return false</returns>
        private String UpRes(string newdid, string resid)
        {
            String LinkCodeUpRes = server + "/build.php?newdid=" + newdid + "&id=" + resid;
            HTTP http1 = new HTTP();
            String sourceHTML1 = http1.GET(LinkCodeUpRes, _cookie); //source html before upgrade

            //if not login, then login again
            if (sourceHTML1.Contains("name = \"login\""))
            {
                doLogin(server, username, password,sourceHTML1);
            }

            //load webpage again
            sourceHTML1 = http1.GET(LinkCodeUpRes, _cookie);//source html before upgrade

            if (sourceHTML1.Contains("<div class=\"button-contents\">"))
            {
                //get code up res
                String codeUpRes = getCodeUpRes(sourceHTML1, resid);
                //send GET to server for upgrading res
                String linkSendingUpRes = server + "/dorf1.php?a=" + resid + "&c=" + codeUpRes;
                String souceHTML2 = http1.GET(linkSendingUpRes, _cookie); //source html after upgrade                                
                return souceHTML2;                
            }
            else
            {
                return null;
            }
        }
        private Boolean firstLogin(String server, String username, String password)
        {
            HTTP http1 = new HTTP();
            String loginUrl = server;
            //lấy source trang login
            String loginPageHTML = Regex.Replace(http1.GET(loginUrl, _cookie), "\t|\r|\n", "");
            //lấy code login
            Match matchLoginCode = Regex.Match(loginPageHTML, "name=\"login\" value=\"(?<loginCode>\\d+)\"");
            //nếu lấy được code login (nghĩa là kết nối được với server)
            if (matchLoginCode.Value != null && matchLoginCode.Value != "")
            {
                //String postData = "name=" + username + "&password=" + password + "&s1=%C4%90%C4%83ng+nh%E1%BA%ADp&w=1366%3A768&login=1308739937";
                String postData = "name=" + username + "&password=" + password + "&s1=Login&w=1024%3A768&login=" + matchLoginCode.Value;
                string source = http1.POST(server + "/dorf1.php", postData, _cookie);

                _cookie = http1.Cookiejar;
                if (source.Contains("logout"))
                {
                    //after login, get list villages name , and coordinates
                    //sau khi login thì dùng souce trả về để lấy thông tin các làng đang có và toạ độ mỗi làng luôn
                    LoadListVillages(source);

                    //log
                    myloger.LogMessageToFile("Finished Login account " + username);
                    return true;
                }
                return false;
            }
                //nếu ko lấy được code (ko kết nối được server)
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Login to server, and return true if finish, and false if cannot login
        /// </summary>
        /// <param name="server">server such as: http://ts4.travian.com </param>
        /// <param name="username">username of gamer</param>
        /// <param name="password">password of gamer</param>
        /// <returns></returns>
        private Boolean doLogin(String server, String username, String password, string html)
        {
            HTTP http1 = new HTTP();
            //bỏ khoảng trống trong source trang login
            String loginPageHTML = Regex.Replace(http1.GET(html, _cookie), "\t|\r|\n", "");
            //lấy code login
            Match matchLoginCode = Regex.Match(loginPageHTML, "name=\"login\" value=\"(?<loginCode>\\d+)\"");
            //nếu lấy được code login (nghĩa là kết nối được với server)
            if (matchLoginCode.Value != null && matchLoginCode.Value != "")
            {
                //String postData = "name=" + username + "&password=" + password + "&s1=%C4%90%C4%83ng+nh%E1%BA%ADp&w=1366%3A768&login=1308739937";
                String postData = "name=" + username + "&password=" + password + "&s1=Login&w=1024%3A768&login=" + matchLoginCode.Value;
                string source = http1.POST(server + "/dorf1.php", postData, _cookie);

                _cookie = http1.Cookiejar;
                if (source.Contains("logout"))
                {
                    return true;
                }
                return false;
            }
            //nếu ko lấy được code (ko kết nối được server)
            else
            {
                return false;
            }         
        }
        /// <summary>
        /// get the code use when send GET to upgrade resource
        /// </summary>
        /// <param name="sourceHTML">source code in HTML</param>
        /// <param name="resid">id of the resource: the position of resource</param>
        /// <returns>String : code</returns>
        private String getCodeUpRes(String sourceHTML, String resid)
        {
            try
            {
                String code = "";
                int ind1 = sourceHTML.LastIndexOf("'dorf1.php?a=" + resid);
                if (ind1 != -1)
                {
                    String substring1 = sourceHTML.Substring(ind1, 40);
                    int ind2 = substring1.IndexOf("c=");
                    code = substring1.Substring(ind2 + 2, 6);
                }
                return code;
            }
            catch
            {
                Console.WriteLine("error while get code up res");
                return null;
            }
        }
        /// <summary>
        /// check in the sourceHTML is this building any house
        /// </summary>
        /// <param name="sourceHTML"></param>
        /// <returns>if no house, return "", return string[0] : amount house, string[1],[2],[3] as name and level of building</returns>
        private String[] whatIsUpgrading(String sourceHTML)
        {
            String[] isbuilding = new String[4];
            isbuilding[0] = null;
            isbuilding[1] = null;
            isbuilding[2] = null;
            isbuilding[3] = null;
            int indTimer1 = sourceHTML.IndexOf("timer1");
            if (indTimer1 == -1)
            {
                isbuilding[0] = "0"; //no house building
            }
            else
            {
                String htmlBuilding1 = sourceHTML.Substring(indTimer1 - 147, 147);
                isbuilding[1] = getHouse(htmlBuilding1);
                isbuilding[0] = "1";

                int indTimer2 = sourceHTML.IndexOf("timer2");
                if (indTimer2 == -1)
                {
                    isbuilding[1] = null;
                }
                else
                {
                    String htmlBuilding2 = sourceHTML.Substring(indTimer2 - 147, 147);
                    isbuilding[2] = getHouse(htmlBuilding2);
                    isbuilding[0] = "2";
                    int indTimer3 = sourceHTML.IndexOf("timer3");
                    if (indTimer3 == -1)
                    {
                        isbuilding[3] = null;
                    }
                    else
                    {
                        String htmlBuilding3 = sourceHTML.Substring(indTimer3 - 147, 147);
                        isbuilding[3] = getHouse(htmlBuilding3);
                        isbuilding[0] = "3";
                    }
                }

            }
            return isbuilding;
        }
        /// <summary>
        /// use to get list of house / resource is building. Only use for travian
        /// when update version, must update this code
        /// </summary>
        /// <param name="htmlCode">source code html</param>
        /// <param name="stringBegin">  </param>
        /// <returns></returns>
        private String getHouse(String htmlCode)
        {
            String stringBegin = "<span class=\"lvl\">";
            string building = null;
            try
            {
                int ind2 = htmlCode.IndexOf(stringBegin);
                int ind1 = ind2;
                while (htmlCode[ind1] != '>')
                {
                    ind1--;
                }
                building = htmlCode.Substring(ind1 + 1, ind2 - ind1 - 1);

                int ind3 = htmlCode.IndexOf(stringBegin) + stringBegin.Length;
                int ind4 = ind3;
                while (htmlCode[ind4] != '<')
                {
                    ind4++;
                }
                building += htmlCode.Substring(ind3, ind4 - ind3);
                return building;
            }
            catch
            {
                Console.WriteLine("error get backward string");
                return null;
            }
        }
        /// <summary>
        /// get string before the string Begin, until meet stopchar
        /// </summary>
        /// <param name="htmlCode">source html</param>
        /// <param name="stopchar">char that stop get string ex: > </param>
        /// <param name="stringBegin">we will get string before this string</param>
        /// <returns></returns>
        private String getStringBackWard(String htmlCode, char stopchar, String stringBegin)
        {
            int ind2 = htmlCode.IndexOf(stringBegin);
            if (ind2 == -1) return "";
            int ind1 = ind2;
            while (htmlCode[ind1] != '>')
            {
                ind1--;
            }
            return htmlCode.Substring(ind1 + 1, ind2 - ind1 - 1);
        }
        /// <summary>
        /// Lấy danh sách tên các làng và toạ độ
        /// get list village names and coordinate of each village
        /// </summary>
        private void LoadListVillages(String html)
        {            
            html = Regex.Replace(html, "\t|\r|\n", "");
            MatchCollection matchCol = Regex.Matches(html, "<ahref=\"\\?newdid=(?<id>\\d+)(?<linhtinh1>.*?)\\((?<X>-?\\d+)&lt;(?<linhtinh2>.*?)&quot;&gt;(?<Y>-?\\d+)\\)(?<linhtinh3>.*?)span&gt;\">(?<villagename>.*?)</a>");
            //amountVillage = matchCol.Count;
            ListVillage = new VillageInfo[matchCol.Count];

            //add villageName, ID,X,Y
            for (int matchi = 0; matchi < matchCol.Count; matchi++)
            {
                ListVillage[matchi] = new VillageInfo();
                ListVillage[matchi].VillageName = matchCol[matchi].Groups["villagename"].ToString();
                ListVillage[matchi].newdid = matchCol[matchi].Groups["id"].ToString();
                ListVillage[matchi].Xcoord = matchCol[matchi].Groups["X"].ToString();
                ListVillage[matchi].Ycoord = matchCol[matchi].Groups["Y"].ToString();
            }
        }
        /// <summary>
        /// Lấy thông tin dorf1 của các làng và đưa vào ListVillage để xử lý sau
        /// </summary>
        private void LoadAllVillage()
        {               
            //with each village, get info res in warehouse   +   res produce           
            for (int i = 0; i < ListVillage.Length; i++)
            {
                LoadDorf1(ListVillage[i].newdid,i);
            }

            cVil = 0; //set current village show in GUI

            //log
            myloger.LogMessageToFile("finished load village");
            toolStripStatusLabel1.Text = "finished";
        }
        /// <summary>
        /// send GET to dorf1 and get infomation to Listvillage
        /// </summary>
        /// <param name="vNewdid">id of village</param>
        /// <param name="i">index of village in Listvillage</param>
        private void LoadDorf1(String vNewdid, int i)
        {
            HTTP http1 = new HTTP();
            String url = server + "/dorf1.php?newdid=" + vNewdid;
            String html = http1.GET(url, _cookie);

            //if not login, then login again
            if (html.Contains("name = \"login\""))
            {
                if (doLogin(server, username, password, html))
                {
                    //get html again after login
                    html = http1.GET(url, _cookie);
                }
            }

            //String html = HTTP.readFile(path);
            html = Regex.Replace(html, "\t|\r|\n", "");
            //load res in warehouse
            MatchCollection matchResWarehouse = Regex.Matches(html, "(?<resw>\\d+/\\d+)");
            ListVillage[i].lumber = matchResWarehouse[0].Value;
            ListVillage[i].clay = matchResWarehouse[1].Value;
            ListVillage[i].iron = matchResWarehouse[2].Value;
            ListVillage[i].crop = matchResWarehouse[3].Value;

            //load res production in 1 hour
            Match matchHTMLResperhour = Regex.Match(html, "<table id=\"production(?<resperhour>.*?)</table>");
            MatchCollection matchResperhour = Regex.Matches(matchHTMLResperhour.Value, "<td class=\"num\">(?<resp>.*?)</td>");
            ListVillage[i].lumberPerHour = matchResperhour[0].Groups["resp"].Value;
            ListVillage[i].clayPerHour = matchResperhour[1].Groups["resp"].Value;
            ListVillage[i].ironPerHour = matchResperhour[2].Groups["resp"].Value;
            ListVillage[i].cropPerHour = matchResperhour[3].Groups["resp"].Value;

            //load res map: type of Land ex: 15c, 9c ..  .
            Match matchVillageMap = Regex.Match(html, "<div id=\"village_map\" class=\"(?<villageMap>.*?)\">");
            ListVillage[i].ResMap = matchVillageMap.Groups["villageMap"].ToString();

            //load res level                
            Match matchHTMLResLevel = Regex.Match(html, "<map(?<linhtinh>.*?)</map>");
            MatchCollection matchResLevel = Regex.Matches(matchHTMLResLevel.Value, "<area href=\"build\\.php\\?id=(?<landid>\\d+)\"(?<linhtinh1>.*?)alt=\"(?<resname>.*?)(?<level>\\d+)\"/>");
            String[] arrReslv = new String[matchResLevel.Count];
            for (int j = 0; j < matchResLevel.Count; j++)
            {
                arrReslv[j] = matchResLevel[j].Groups["landid"].Value + ","
                    + matchResLevel[j].Groups["resname"].Value + ","
                    + matchResLevel[j].Groups["level"].Value;
            }
            ListVillage[i].resLevel = arrReslv;

            //load house is building
            Match matchHTMLBuildingContract = Regex.Match(html, "<table cellpadding=\"1\" cellspacing=\"1\" id=\"building_contract\">(?<linhtinh>.*?)</table>");
            MatchCollection matchBuildingContract = Regex.Matches(matchHTMLBuildingContract.Value, "<td>(?<buildingname>.*?)<span class=\"lvl\">(?<level>.*?)</span>(?<linhtinh2>.*?)timer(?<linhtinh3>.*?)\">(?<neededtime>.*?)</span>(?<linhtinh4>.*?)</td>");
            String[] arrtemp = new String[3];
            for (int j = 0; j < matchBuildingContract.Count; j++)
            {
                arrtemp[j] = matchBuildingContract[j].Groups["buildingname"].Value
                    + "," + matchBuildingContract[j].Groups["level"].Value
                    + "," + matchBuildingContract[j].Groups["neededtime"].Value;
            }
            for (int j = matchBuildingContract.Count; j < 3; j++)
            {
                arrtemp[j] = "";
            }
            ListVillage[i].HouseUpgrading = arrtemp;
            //Load remain time finished builing which is in upgrading & prepare randomtime
            if (matchBuildingContract.Count > 0)
            {
                ListVillage[i].RemainTimeUpgrading = matchBuildingContract[matchBuildingContract.Count - 1].Groups["neededtime"].Value;
                ListVillage[i].randomTime = random.Next(20, 35);
            }
            else
            {
                ListVillage[i].RemainTimeUpgrading = "00:00:00";
                ListVillage[i].randomTime = 10;
            }

        }
        private void LoadDorf2(String vNewdid, int i)
        {
            HTTP http1 = new HTTP();
            String url = server + "/dorf2.php?newdid=" + vNewdid;
            String html = http1.GET(url, _cookie);

            //if not login, then login again
            if (html.Contains("name = \"login\""))
            {
                if (doLogin(server, username, password, html))
                {
                    //get html again after login
                    html = http1.GET(url, _cookie);
                }
            }

            //String html = HTTP.readFile(path);
            html = Regex.Replace(html, "\t|\r|\n", "");

            //load house level                
            Match matchHTMLHouseLevel = Regex.Match(html, "<map(?<linhtinh>.*?)</map>");
            MatchCollection matchResLevel = Regex.Matches(matchHTMLHouseLevel.Value, "<area href=\"build\\.php\\?id=(?<landid>\\d+)\"(?<linhtinh1>.*?)alt=\"(?<resname>.*?)(?<level>\\d+)\"/>");
            String[] arrHouselv = new String[matchResLevel.Count];
            for (int j = 0; j < matchResLevel.Count; j++)
            {
                arrHouselv[j] = matchResLevel[j].Groups["landid"].Value + ","
                    + matchResLevel[j].Groups["resname"].Value + ","
                    + matchResLevel[j].Groups["level"].Value;
            }
            ListVillage[i].resLevel = arrHouselv;

            //load house is building
            Match matchHTMLBuildingContract = Regex.Match(html, "<table cellpadding=\"1\" cellspacing=\"1\" id=\"building_contract\">(?<linhtinh>.*?)</table>");
            MatchCollection matchBuildingContract = Regex.Matches(matchHTMLBuildingContract.Value, "<td>(?<buildingname>.*?)<span class=\"lvl\">(?<level>.*?)</span>(?<linhtinh2>.*?)timer(?<linhtinh3>.*?)\">(?<neededtime>.*?)</span>(?<linhtinh4>.*?)</td>");
            String[] arrtemp = new String[3];
            for (int j = 0; j < matchBuildingContract.Count; j++)
            {
                arrtemp[j] = matchBuildingContract[j].Groups["buildingname"].Value
                    + "," + matchBuildingContract[j].Groups["level"].Value
                    + "," + matchBuildingContract[j].Groups["neededtime"].Value;
            }
            for (int j = matchBuildingContract.Count; j < 3; j++)
            {
                arrtemp[j] = "";
            }
            ListVillage[i].HouseUpgrading = arrtemp;

            //Load remain time finished builing which is in upgrading & prepare randomtime
            if (matchBuildingContract.Count > 0)
            {
                ListVillage[i].RemainTimeUpgrading = matchBuildingContract[matchBuildingContract.Count - 1].Groups["neededtime"].Value;
                ListVillage[i].randomTime = random.Next(25, 35);
            }
            else
            {
                ListVillage[i].RemainTimeUpgrading = "00:00:00";
                ListVillage[i].randomTime = 0;
            }
        }
        /// <summary>
        /// read data from source HTML of dorf1.php
        /// </summary>
        /// <param name="villageIndex">index of village will read to</param>
        /// <param name="html">the source HTML of village</param>
        private void readDorf1HTML(int villageIndex, String html)
        {
            //if return page is dorf1
            if (html.Contains("<table id=\"production\"")) 
            {           
                html = Regex.Replace(html, "\t|\r|\n", ""); 
                //load res in warehouse
                MatchCollection matchResWarehouse = Regex.Matches(html, "(?<resw>\\d+/\\d+)");
                ListVillage[villageIndex].lumber = matchResWarehouse[0].Value;
                ListVillage[villageIndex].clay = matchResWarehouse[1].Value;
                ListVillage[villageIndex].iron = matchResWarehouse[2].Value;
                ListVillage[villageIndex].crop = matchResWarehouse[3].Value;

                //load res production in 1 hour
                Match matchHTMLResperhour = Regex.Match(html, "<table id=\"production(?<resperhour>.*?)</table>");
                MatchCollection matchResperhour = Regex.Matches(matchHTMLResperhour.Value, "<td class=\"num\">(?<resp>.*?)</td>");
                ListVillage[villageIndex].lumberPerHour = matchResperhour[0].Groups["resp"].Value;
                ListVillage[villageIndex].clayPerHour = matchResperhour[1].Groups["resp"].Value;
                ListVillage[villageIndex].ironPerHour = matchResperhour[2].Groups["resp"].Value;
                ListVillage[villageIndex].cropPerHour = matchResperhour[3].Groups["resp"].Value;
            
                //load res map: type of Land ex: 15c, 9c ..  .
                Match matchVillageMap = Regex.Match(html, "<div id=\"village_map\" class=\"(?<villageMap>.*?)\">");
                ListVillage[villageIndex].ResMap = matchVillageMap.Groups["villageMap"].ToString();

                //load res level                
                Match matchHTMLResLevel = Regex.Match(html, "<map(?<linhtinh>.*?)</map>");                
                MatchCollection matchResLevel = Regex.Matches(matchHTMLResLevel.Value, "<area href=\"build\\.php\\?id=(?<landid>\\d+)\"(?<linhtinh1>.*?)alt=\"(?<resname>.*?)(?<level>\\d+)\"/>");
                String[] arrReslv = new String[matchResLevel.Count];
                for (int j = 0; j < matchResLevel.Count; j++)
                {
                    arrReslv[j] = matchResLevel[j].Groups["landid"].Value + "," 
                        + matchResLevel[j].Groups["resname"].Value + "," 
                        + matchResLevel[j].Groups["level"].Value;
                }
                ListVillage[villageIndex].resLevel = arrReslv;

                //load house is building
                Match matchHTMLBuildingContract = Regex.Match(html, "<table cellpadding=\"1\" cellspacing=\"1\" id=\"building_contract\">(?<linhtinh>.*?)</table>");
                MatchCollection matchBuildingContract = Regex.Matches(matchHTMLBuildingContract.Value, "<td>(?<buildingname>.*?)<span class=\"lvl\">(?<level>.*?)</span>(?<linhtinh2>.*?)timer(?<linhtinh3>.*?)\">(?<neededtime>.*?)</span>(?<linhtinh4>.*?)</td>");
                String[] arrtemp = new String[3];
                for (int j = 0; j < matchBuildingContract.Count; j++)
                {
                    arrtemp[j] = matchBuildingContract[j].Groups["buildingname"].Value
                        + "," + matchBuildingContract[j].Groups["level"].Value
                        + "," + matchBuildingContract[j].Groups["neededtime"].Value;
                }
                for (int j = matchBuildingContract.Count; j < 3; j++)
                {
                    arrtemp[j] = "";
                }
                ListVillage[villageIndex].HouseUpgrading = arrtemp;
                //Load remain time finished builing which is in upgrading & prepare randomtime
                ListVillage[villageIndex].RemainTimeUpgrading = matchBuildingContract[matchBuildingContract.Count - 1].Groups["neededtime"].Value;
                ListVillage[villageIndex].randomTime = random.Next(20, 30);
            }        
        }       
        /// <summary>
        /// show the village to GUI
        /// </summary>
        /// <param name="Vinfo">village infomation</param>
        private void GUIShowVillage(VillageInfo Vinfo)
        {            
            //Hiển thị level mỏ res lên trên ảnh
            //load level to image
            label1.Text = Vinfo.resLevel[0].ToString().Split(',')[2];
            label2.Text = Vinfo.resLevel[1].ToString().Split(',')[2];
            label3.Text = Vinfo.resLevel[2].ToString().Split(',')[2];
            label4.Text = Vinfo.resLevel[3].ToString().Split(',')[2];
            label5.Text = Vinfo.resLevel[4].ToString().Split(',')[2];
            label6.Text = Vinfo.resLevel[5].ToString().Split(',')[2];
            label7.Text = Vinfo.resLevel[6].ToString().Split(',')[2];
            label8.Text = Vinfo.resLevel[7].ToString().Split(',')[2];
            label9.Text = Vinfo.resLevel[8].ToString().Split(',')[2];
            label10.Text = Vinfo.resLevel[9].ToString().Split(',')[2];
            label11.Text = Vinfo.resLevel[10].ToString().Split(',')[2];
            label12.Text = Vinfo.resLevel[11].ToString().Split(',')[2];
            label13.Text = Vinfo.resLevel[12].ToString().Split(',')[2];
            label14.Text = Vinfo.resLevel[13].ToString().Split(',')[2];
            label15.Text = Vinfo.resLevel[14].ToString().Split(',')[2];
            label16.Text = Vinfo.resLevel[15].ToString().Split(',')[2];
            label17.Text = Vinfo.resLevel[16].ToString().Split(',')[2];
            label18.Text = Vinfo.resLevel[17].ToString().Split(',')[2];

            //load the image with type of res such ash 15c, 9c, 6c . . .
            //Hiển thị hình ảnh tương ứng với loại map
            switch (Vinfo.ResMap) 
            {
                case "f1": picRes.Image = Properties.Resources.f1; break;
                case "f2": picRes.Image = Properties.Resources.f2; break;
                case "f3": picRes.Image = Properties.Resources.f3; break;
                case "f4": picRes.Image = Properties.Resources.f4; break;
                case "f5": picRes.Image = Properties.Resources.f5; break;
                case "f6": picRes.Image = Properties.Resources.f6; break;
                case "f7": picRes.Image = Properties.Resources.f7; break;
                case "f8": picRes.Image = Properties.Resources.f8; break;
                case "f9": picRes.Image = Properties.Resources.f9; break;
                case "f10": picRes.Image = Properties.Resources.f10; break;
                case "f11": picRes.Image = Properties.Resources.f11; break;
                case "f12": picRes.Image = Properties.Resources.f12; break;
                case "f13": picRes.Image = Properties.Resources.f99; break;
                default: toolStripStatusLabel1.Text = "cannot load image"; break;
            }
            //Show res in the warehouse
            lbLumberWarehouse.Text = Vinfo.lumber;
            lbClayWarehouse.Text = Vinfo.clay;
            lbIronWarehouse.Text = Vinfo.iron;
            lbCropWarehouse.Text = Vinfo.crop;

            //show the progress bar
            lumberPercent.Maximum = clayPercent.Maximum = ironPercent.Maximum  = Convert.ToInt32(Vinfo.lumber.Split('/')[1]);
            cropPercent.Maximum = Convert.ToInt32(Vinfo.crop.Split('/')[1]);
            lumberPercent.Value = Convert.ToInt32( Vinfo.lumber.Split('/')[0]);
            clayPercent.Value = Convert.ToInt32(Vinfo.clay.Split('/')[0]);
            ironPercent.Value = Convert.ToInt32(Vinfo.iron.Split('/')[0]);
            cropPercent.Value = Convert.ToInt32(Vinfo.crop.Split('/')[0]);

            //Show amount res are produced in 1 hour
            lbLumberHour.Text = Vinfo.lumberPerHour;
            lbClayHour.Text = Vinfo.clayPerHour;
            lbIronHour.Text = Vinfo.ironPerHour;
            lbCropHour.Text = Vinfo.cropPerHour;

            //load the building is in upgrade
            if (Vinfo.HouseUpgrading.Length > 0 && Vinfo.HouseUpgrading != null)
            {
                for (int i = 0; i < Vinfo.HouseUpgrading.Length; i++)
                {
                    if (Vinfo.HouseUpgrading[i] != "")
                    {
                        String[] tmp1 = Vinfo.HouseUpgrading[i].Split(',');
                        switch (i)
                        {
                            case 0:
                                lblInBuilding1.Text = tmp1[0] + tmp1[1];
                                break;
                            case 1:
                                lblInBuilding2.Text = tmp1[0] + tmp1[1];
                                break;
                            case 2:
                                lblInBuilding3.Text = tmp1[0] + tmp1[1];
                                break;
                        }
                    }
                    else
                    {
                        switch (i)
                        {
                            case 0:
                                lblInBuilding1.Text = "";
                                break;
                            case 1:
                                lblInBuilding2.Text = "";
                                break;
                            case 2:
                                lblInBuilding3.Text = "";
                                break;
                        }
                    }
                }
                lblFinish3.Text = Vinfo.RemainTimeUpgrading;
            }
            else
            {
                lblInBuilding1.Text = "";
                lblInBuilding2.Text = "";
                lblInBuilding3.Text = "";
                lblFinish2.Text = "";
                lblFinish3.Text = "";
            }
            //show listupgrade
            ListTaskWaiting.Items.Clear();
            foreach (UpgradeTask uptask in Vinfo.ListUpgrade)
            {
                ListTaskWaiting.Items.Add(uptask.nameBuilding + uptask.level);
            }
        }
        /// <summary>
        /// Hiển thị danh sách làng lên tabpage, và hiển thị res có trong kho
        /// </summary>
        private void GUIShowListVillage()
        {
            //dispose all old tabpage
            tabControl1.Controls.Clear();            
            //create tabpage for each village
            for (int i = 0; i < ListVillage.Length; i++)
            {
                ListTabpageVillage[i].Text = ListVillage[i].VillageName;
                ListTabpageVillage[i].Tag = ListVillage[i].newdid;
                tabControl1.Controls.Add(ListTabpageVillage[i]);
            }
        }
        /// <summary>
        /// click vào tab làng nào thì thông tin làng đó hiện lên
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabchange(object sender, EventArgs e)
        {   
            foreach (VillageInfo vinfo in ListVillage)
            {
                if ((vinfo.VillageName == tabControl1.SelectedTab.Text) && (vinfo.newdid == tabControl1.SelectedTab.Tag.ToString()))
                {
                    cVil = tabControl1.SelectedIndex;
                    GUIShowVillage(vinfo);
                    break;
                }
            }
            toolStripStatusLabel1.Text = "current village: " + tabControl1.SelectedTab.Text;
        }
        /// <summary>
        /// Tạo mới một task trong tasklist, đồng thời thêm task vào list trong GUI, khi mỗi button được click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param> 
        private void addListUpRes(object sender, MouseEventArgs e)
        {
            if (ListVillage.Length != 0)
            {
                UpgradeTask task = null;
                Label b1 = (Label)sender;
                //create new task upgrade res for adding to list
                //tạo mới task để add vào
                //Kiểm tra trong list xem có task nào với resid đó chưa                
                int indx = ListVillage[cVil].ListUpgrade.FindLastIndex(delegate(UpgradeTask deTask) { if ( deTask.landid == b1.Tag.ToString()) return true; else return false; });
                //nếu có rồi thì lấy giá trị level cuối cùng của mỏ đó + 1 rồi tạo task
                if (indx >= 0)
                {
                    String building = ListVillage[cVil].resLevel[byte.Parse( b1.Tag.ToString())-1].Split(',')[1];
                    int Uplevel = ListVillage[cVil].ListUpgrade[indx].level + 1 ;
                    task = new UpgradeTask(ListVillage[cVil].newdid, b1.Tag.ToString(), Uplevel, building);
                }
                //nếu chưa có thì add task với level là level hiện tại của mỏ res đó + 1
                else
                {
                    String building = ListVillage[cVil].resLevel[byte.Parse( b1.Tag.ToString())-1].Split(',')[1];
                    int level = byte.Parse( ListVillage[cVil].resLevel[byte.Parse( b1.Tag.ToString())-1].Split(',')[2]) + 1;
                    task = new UpgradeTask(ListVillage[cVil].newdid, b1.Tag.ToString(), level,building);
                }
                
                switch (e.Button)
                {
                    //nếu là click chuột trái thì add task vào
                    case MouseButtons.Left:
                        ListVillage[tabControl1.SelectedIndex].ListUpgrade.Add(task);
                        ListTaskWaiting.Items.Add(task.nameBuilding + task.level.ToString()); //add to listbox in GUI
                        break;

                    //nếu là click chuột phải thì bỏ task đi
                    case MouseButtons.Right:
                        for (int i = ListVillage[tabControl1.SelectedIndex].ListUpgrade.Count - 1; i >= 0; i--)
                        {
                            if (ListVillage[tabControl1.SelectedIndex].ListUpgrade[i].newdid == task.newdid)
                            {
                                ListVillage[tabControl1.SelectedIndex].ListUpgrade.RemoveAt(i);
                                break;
                            }
                        }
                        ListTaskWaiting.Items.Remove(b1.Tag); //remove from listbox in GUI                        

                        //log                        
                        myloger.LogMessageToFile("Finished remove task->" + task.newdid);
                        break;

                    default:
                        break;
                }
            }
            else
            {
                MessageBox.Show("error, no current newdid");
            }
        }
        private void MoveTaskUp_Click(object sender, EventArgs e)
        {
            //change position on GUI
            if (ListTaskWaiting.SelectedIndex != 0 && ListTaskWaiting.Items.Count > 0)
            {
                String temp = ListTaskWaiting.SelectedItem.ToString();
                ListTaskWaiting.Items[ListTaskWaiting.SelectedIndex] = ListTaskWaiting.Items[(ListTaskWaiting.SelectedIndex - 1)];
                ListTaskWaiting.Items[(ListTaskWaiting.SelectedIndex - 1)] = temp;
                

                //change position on ListUpgrade
                UpgradeTask taskTemp = ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex];
                ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex] = ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex - 1];
                ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex - 1] = taskTemp;

                //return to the task has been move.
                ListTaskWaiting.SelectedIndex = ListTaskWaiting.SelectedIndex - 1;
            }
            
            
        }
        private void MoveTaskDown_Click(object sender, EventArgs e)
        {
            if (ListTaskWaiting.SelectedIndex < ListTaskWaiting.Items.Count - 1 && ListTaskWaiting.Items.Count > 0 )
            {
                //change position on GUI
                String temp = ListTaskWaiting.SelectedItem.ToString();
                ListTaskWaiting.Items[ListTaskWaiting.SelectedIndex] = ListTaskWaiting.Items[(ListTaskWaiting.SelectedIndex + 1)];
                ListTaskWaiting.Items[(ListTaskWaiting.SelectedIndex + 1)] = temp;

                //change position on ListUpgrade
                UpgradeTask taskTemp = ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex];
                ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex] = ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex + 1];
                ListVillage[tabControl1.SelectedIndex].ListUpgrade[ListTaskWaiting.SelectedIndex + 1] = taskTemp;
                
                //return to the task has been move.
                ListTaskWaiting.SelectedIndex = ListTaskWaiting.SelectedIndex + 1;
            }
        }
        private void ClearTask_Click(object sender, EventArgs e)
        {
            ListTaskWaiting.Items.Clear();
            ListVillage[tabControl1.SelectedIndex].ListUpgrade.Clear();
        }
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            LoadDorf1(ListVillage[cVil].newdid, cVil);
            GUIShowVillage(ListVillage[cVil]);
        }
        private void showForm(object sender, MouseEventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }
        private void Form1_Resize(object sender, EventArgs e)
        {
            if (System.Windows.Forms.FormWindowState.Minimized == WindowState)
            {
                Hide();
            }
        }


        /// <summary>
        /// Button start và stop BOT
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonLogin_Click(object sender, EventArgs e)
        {
            // prepare account
            String[] value = account[comboBox1.SelectedIndex].Split(',');
            server = value[0];
            username = value[1];
            password = value[2];

            //process
            if (startStop == false)
            {
                toolStripStatusLabel1.Text = "Login . . .";
                if (firstLogin(server, username, password))
                {
                    toolStripStatusLabel1.Text = "Load Villages";
                    LoadAllVillage();
                    GUIShowListVillage();  //hien thi danh sach lang                
                    GUIShowVillage(ListVillage[0]); //after load, show the first village
                    startStop = !startStop;
                    timer1.Start();
                    timer2.Start();
                    btnLogin.Text = ". . . ";
                    btnLogin.Enabled = false;
                }
                else
                {
                    MessageBox.Show("cannot login");
                    return;
                }

            }
            else
            {
                timer1.Stop();
                timer2.Stop();
                timer1.Start();
                timer2.Stop();
                toolStripStatusLabel1.Text = "Bot is stopping";
                startStop = !startStop;
                btnLogin.Text = "Start";
            }
            //disable combobox
            comboBox1.Enabled = false;
        }
        void timer1_Tick(object sender, EventArgs e)
        {
            //with each village, count down timer when have building
            for (int i = 0; i < ListVillage.Length; i++)
            {
                if (ListVillage[i].RemainTimeUpgrading != "00:00:00")
                {
                    ListVillage[i].RemainTimeUpgrading = LibFunction.countDown(ListVillage[i].RemainTimeUpgrading);
                    //show to GUI
                    //hiển thị thời gian chờ nhà xây xong lên GUI
                    lblFinish3.Text = ListVillage[tabControl1.SelectedIndex].RemainTimeUpgrading;
                }
                else //nếu không còn công trình nào đang xây (đã xây xong hết) thì set nhà đang xây về = ""
                {
                    ListVillage[i].HouseUpgrading[0] = "";
                    ListVillage[i].HouseUpgrading[1] = "";
                    ListVillage[i].HouseUpgrading[2] = "";
                    // nếu làng đang duyệt trùng với làng đang hiển thị thì show ra màn hình
                    //if village is view in GUI, then set in GUI
                    if (i == cVil)
                    {
                        lblInBuilding1.Text = ListVillage[i].HouseUpgrading[0];
                        lblInBuilding2.Text = ListVillage[i].HouseUpgrading[1];
                        lblInBuilding3.Text = ListVillage[i].HouseUpgrading[2];
                        lblFinish3.Text = "";
                    }
                    //nếu trong danh sách chờ nâng cấp có mỏ đang chờ nâng cấp thì :
                    //if have task upgrade then
                    if (ListVillage[i].ListUpgrade.Count > 0)
                    {
                        if (ListVillage[i].randomTime != 0)
                        {
                            //giảm thời gian random
                            ListVillage[i].randomTime--;
                            myloger.LogMessageToFile(ListVillage[i].VillageName + ",randomtime = " + ListVillage[i].randomTime.ToString());
                            if (i == tabControl1.SelectedIndex)  //nếu làng đang xử lý đúng với làng show trên GUI thì hiện ra randomtime
                            {
                                lblRandomTime.Text = (ListVillage[i].randomTime).ToString();
                                
                            }
                        }
                        else // nếu random time =0 rồi thì đưa vào todolist
                        {
                            UpgradeTask task = new UpgradeTask(ListVillage[i].ListUpgrade[0].newdid, ListVillage[i].ListUpgrade[0].landid);
                            todoList.Add(task);
                            //remove from task
                            ListVillage[i].ListUpgrade.RemoveAt(0);

                            //vì chạy xong dòng trên, village vẫn chưa được cập nhật, nên với task tiếp theo, thời gian chờ  = 00:00:00
                            //và random time = 0 nên nó đưa task tiếp theo vào để thực thi luôn
                            //cái này để ngăn chặn việc đó xảy ra
                            ListVillage[i].randomTime = random.Next(25, 35);
                            //myloger.LogMessageToFile(ListVillage[i].VillageName + ", random time next task"
                            //    + ListVillage[i].randomTime.ToString());

                        }
                    }
                }
            }
        }
        void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //upgrade house, if successfull, return html, load html to listvillage, and show to GUI if current is that village

            //with each todowork
            for (int mustDoInd = 0; mustDoInd < todoList.Count; mustDoInd++)
            {
                UpgradeTask task = (UpgradeTask)todoList[0];

                //post data để upgrade rồi lấy chuỗi HTML trả về
                String HTMLafterUpgrade = UpRes(task.newdid, task.landid);
                //nếu chuỗi trả về khác null có nghĩa là làm thành công 
                //và khác rỗng có nghĩa là không bị disconnect
                //if upgrade successfull
                if (HTMLafterUpgrade != null && HTMLafterUpgrade != "")
                {
                    int i;
                    for (i = 0; i < ListVillage.Length; i++)
                    {
                        if (ListVillage[i].newdid == task.newdid)
                        {
                            //up res thành công thì lấy thông tin trả về để cập nhật lại làng đó
                            //load infomation from html return to listVillage
                            readDorf1HTML(i, HTMLafterUpgrade);
                            break;
                        }
                    }
                    //remove from todolist
                    if (todoList.Count > 0)
                    {
                        todoList.RemoveAt(0);
                    }

                    //show to GUI if the village is current
                    if (i == cVil)
                    {
                        deGUIshowvillage GUIshowvillage1 = new deGUIshowvillage(GUIShowVillage);
                        BeginInvoke(GUIshowvillage1, ListVillage[i]);
                    }
                    myloger.LogMessageToFile("finished send upgrade " + task.newdid + "," + task.nameBuilding + task.level);
                }
                //nếu không upgrade được do thiếu res hay thiếu lúa
                //thì insert lại vào task  và set thời gian random cho nó đếm lui.
                else
                {
                    //insert lại task vào trong hàng đợi.
                    //hàm for này là để tìm xem task đó nó của village nào thông qua newdid
                    for (int i = 0; i < ListVillage.Length; i++)
                    {
                        if (ListVillage[i].newdid == task.newdid)
                        {
                            ListVillage[i].ListUpgrade.Insert(0, task);
                            //set lại thời gian đợi.
                            ListVillage[i].randomTime = random.Next(180, 360);
                            //log
                            myloger.LogMessageToFile("fail upres, add ngược lại, làng " + ListVillage[i].VillageName + " , task: "+ task.nameBuilding + task.level);
                            break;
                        }
                    }
                    //remove from todolist
                    //bỏ task này ra khỏi todolist
                    if (todoList.Count > 0)
                    {
                        todoList.RemoveAt(0);
                    }
                    myloger.LogMessageToFile("cannot upgrade");
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //prepare cookie
            _cookie = new CookieContainer();

            //timer 1: count down
            timer1.Interval = 1000;
            timer1.Tick +=new EventHandler(timer1_Tick);

            //timer 2: excute task
            timer2.Interval = 5000;
            timer2.Elapsed += new System.Timers.ElapsedEventHandler(timer2_Elapsed);

            //init tabPage
            for (int i = 0; i < ListTabpageVillage.Length; i++)
            {
                ListTabpageVillage[i] = new TabPage();
                ListTabpageVillage[i].Name = "TabPage" + (i+1).ToString();
            }
            //account
            account = new string[7];
            account[0] = "http://ts8.travian.com.vn,jerryno7,meomi1987";
            account[1] = "http://ts8.travian.com.vn,dinhbeone,meomi1987";            
            account[2] = "http://ts2.travian.com,jerryno7,meomi1987";
            account[3] = "http://ts2.travian.com,TheDragon80,meomi1987";
            //account[4] = "http://ts8.travian.com.vn,kphisilver,diamond";
            //account[5] = "http://ts8.travian.com.vn,fsoft,thanhbn";
            //account[6] = "http://ts8.travian.com.vn,heokoy,ddowifnhucj";
            comboBox1.SelectedIndex = 0;

            //set transparent
            label1.Parent = picRes;
            label2.Parent = picRes;
            label3.Parent = picRes;
            label4.Parent = picRes;
            label5.Parent = picRes;
            label6.Parent = picRes;
            label7.Parent = picRes;
            label8.Parent = picRes;
            label9.Parent = picRes;
            label10.Parent = picRes;
            label11.Parent = picRes;
            label12.Parent = picRes;
            label13.Parent = picRes;
            label14.Parent = picRes;
            label15.Parent = picRes;
            label16.Parent = picRes;
            label17.Parent = picRes;
            label18.Parent = picRes;
            //new area log
            myloger.LogMessageToFile("---------------------------------------");
        }



  

 
    }
}



